package demo1;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.awt.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.stream.Collectors;

public class HashSetDemo {
    /**
     * use hashMap or hashTable
     */
    public boolean adjustUnique(){
        HashSet<Character> set = new HashSet<>();
        String testStr  = "abcddqaeuioq";
        char[] chars = testStr.toCharArray();
        for (int i =0;i< chars.length;i++){
            boolean contains = set.add(chars[i]);
            if(!contains){
                return false;
            }
        }
        return true;
    }

    private class HashSetSimulate<T>{
        transient private Object[] arrays;
        public HashSetSimulate(int size){
            // array go on to grow, until overflow
            arrays =new Object[size];
        }
        /**
         * 1. hash
         */
        public boolean add(T t){
            int tt = Objects.hashCode(t);
            for (int i=0;i<arrays.length;i++){
                if(Objects.hashCode(arrays[i])==tt){ // equals 判断方式
                    return false;
                }
            }
            arrays[arrays.length-1]=t;
            return true;
        }
    }
    public boolean adjustUniqueWithoutSet(){
        HashSetSimulate<Character> set = new HashSetSimulate<>(12);
        String testStr  = "abcddqaeuioq";
        char[] chars = testStr.toCharArray();
        for (int i =0;i< chars.length;i++){
            boolean contains = set.add(chars[i]);
            if(!contains){
                return false;
            }
        }
        return true;
    }
    public URLParam makeUrlParam(String str,int length){
        return new URLParam(str,length);
    }
    public StringCompress makeStringCompress(String str){
        return new StringCompress(str);
    }
    public Palindrome makePalindrome(String str){
        return new Palindrome(str);
    }
    public MatrixRoll makeMatrixRoll(){
        return new MatrixRoll();
    }
    public MatrixClear makeMatrixClear(){
        return new MatrixClear();
    }
    public StringRoll makeStringRoll(String str1,String str2){
        return new StringRoll(str1,str2);
    }
    public EqualsClass makeClass(String str){
        EqualsClass equalsClass = new EqualsClass(str);
        return equalsClass;
    }
    /**
     * 1. str1 ="abc"
     * 2. str1 ="cba"
     * 确定字符串，排序后， 是否相等，
     */
    public class EqualsClass{
        private String str;
        private boolean isAsc=true;
        public EqualsClass(){}
        public EqualsClass(String str){this.str=str;}

        public String getStr() {
            return str;
        }

        private void sort(){
            char[] chars = str.toCharArray();
            Arrays.sort(chars); // use dualPivot
            this.str=new String(chars);
        }
       private boolean equals(EqualsClass other){
            return str.equals(other.getStr());
       }
    }
    public boolean isEqualsAfterSort(EqualsClass equalsClass1,EqualsClass equalsClass2){
        return equalsClass1.equals(equalsClass1);
    }

    @NoArgsConstructor
    @AllArgsConstructor
    public class URLParam{
        private String str;
        private int length;
        public String format(){
            char[] newArrays = new char[100];

            char[] chars = str.toCharArray();
            int z=0;
            for (int i=0,j=0;i<length;i++,j++){
                if(chars[i]==' '){
                    newArrays[j]='%';
                    newArrays[++j]='2';
                    newArrays[++j]='0';
                }else{
                    newArrays[j]=chars[i];
                }
                z=j;
            }
            char[] chars1 = new char[z + 1];
            System.arraycopy(newArrays,0,chars1,0,z+1);

            return new String(chars1);
        }

    }
    public String URLformat(URLParam urlParam){
        return urlParam.format();
    }
    @NoArgsConstructor
    @AllArgsConstructor
    public class Palindrome{
        private String str;
        public boolean isPalindrome(){
            // tactcoa
            // actotca
            this.str=str.toLowerCase(Locale.ROOT).replace(" ","");

            HashMap map = new HashMap<String,Boolean>();
            char[] chars = str.toCharArray();
            for (int i=0;i<chars.length;i++){
                Object put = map.put(chars[i], false);
                if(put!=null){
                    map.put(chars[i],true);
                }
            }
            Collection values = map.values();
            long count = values.stream().filter(o -> {
                return !(Boolean) o;
            }).count();
            return count<2;
        }
    }

    public boolean isPalindrome(Palindrome palindrome){
        return palindrome.isPalindrome();
    }
    @Setter
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    private class CharCount{
        private char destchar;
        private int count;
        public void increament(){
            count++;
        }
    }
    /**
     * string compress
     * aabbcccdeed => a2b2c3d1e2d1
     * aabccccccaaa => a2b1c5a3
     */
    @AllArgsConstructor
    @NoArgsConstructor
    public class StringCompress{
        private String str;
        public String compress(){
            /**
             * time: O(n)
             * volumn: O(n) =》LinkedList
             */
           LinkedList<CharCount> charCounts = new LinkedList<CharCount>();
            StringBuilder sb = new StringBuilder();

            char[] chars = this.str.toCharArray();
            char charTmp ='5';
            int count=0;
            boolean flag =false;
            for (int i=0;i<chars.length;i++){

                if(charTmp==chars[i]){
                    flag=true;
                    CharCount charCount = charCounts.removeLast();
                    charCount.increament();
                    charCounts.addLast(charCount);
                }else{
                    charCounts.addLast(new CharCount(chars[i],1));
                    charTmp=chars[i];

                }
            }
            if(!flag){
                return this.str;
            }else{
                charCounts.stream().forEach(charCount -> {
                    sb.append(charCount.getDestchar()).append(charCount.getCount());
                });
                return sb.toString();
            }

        }

    }
    public String printAfterCompress(StringCompress stringCompress){
        return stringCompress.compress();
    }
    @AllArgsConstructor
    @NoArgsConstructor
    private class Point{
        private int x;
        private int y;
    }
    @NoArgsConstructor
    @AllArgsConstructor
    public  class MatrixRoll{
        int x=3;
        int y=3;

        // make up the matrix
        public  int[][] makeUpMatrix(){
           /**
            * 逆时针90度
            * 1 2      => 2 1
            * 0 1         1 0
            *
              => 旋转点不同
            2,3,4,  => 3,4,2 =>
            1,2,3,     2,3,2
            0,1,2,     1,1,0




            * 多个表格，分次序进行旋转
            */
            int[][] arr = new int[x][y];
            for (int i=0;i<x;i++){ // 1
                for (int j=0;j<y;j++){ // 0,1
                    arr[i][j]=i+j;
                }
            }
            printArrays(arr);
            return arr;
        }
        public void printArrays(int[][] arrays){
            for (int i=0;i<x;i++){ // 0,0
                for (int j=0;j<y;j++){ // 0,1
                    System.out.print(arrays[i][j]+",");;
                }
                System.out.println();
            }
        }
        public int[][] roll(){
            int[][] arr = makeUpMatrix();
            int tmp=0,tmp1=0,tmp2=0,tmp3=0;
            for (int i=0;i<x-1;i++){// 0,0 \0,1 \1,0 \1,1
                // 0,0 \0,1 \0,2 \1,1 \1,2 ,
                for (int j=0;j<y-1;j++){
                    // (x,y)=>0,0
                    tmp=arr[i][j+1]; //
                    arr[i][j+1] = arr[i][j];

                    tmp1 = arr[i+1][j+1];
                    arr[i+1][j+1]=tmp;

                    tmp2=arr[i+1][j];
                    arr[i+1][j]=tmp1;

                    tmp3=arr[i][j];
                    arr[i][j]=tmp2;
                }
            }
            printArrays(arr);
            return arr;

        }
    }
    @AllArgsConstructor
    @NoArgsConstructor
    public class MatrixClear{
        private int x=3;
        private int y=4;
        // foreach the list get the 0 ,and setting  x and y is 0
/** M*N= 3 * 4
 * 0,1,2,3
 * 1,2,0,4 =>
 * 2,3,0,5
 */
        public void clear(){
            int[][] arrays = makeUpMatrix();
            ArrayList<Point> arrayList = new ArrayList<Point>();
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    if(arrays[i][j]==0){
                        arrayList.add(new Point(i,j));
                    }
                }
            }
            System.out.println("============point.================");
            arrayList.stream().forEach(arr->{
                System.out.println(arr.x+"--"+arr.y);
                for (int ii=0;ii<y;ii++){
                    arrays[arr.x][ii]=0;
                }
                for (int jj=0;jj<x;jj++){
                    arrays[jj][arr.y]=0;
                }
            });
            printArrays(arrays);

        }
        // make up the matrix
        public  int[][] makeUpMatrix(){
            int[][] arr = new int[x][y];
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    arr[i][j]=i+j;
                }
            }
            // for example.
            arr[1][2]=0;
            arr[2][2]=0;
            printArrays(arr);
            return arr;
        }
        public void printArrays(int[][] arrays){
            for (int i=0;i<x;i++){ // 0,0
                for (int j=0;j<y;j++){ // 0,1
                    System.out.print(arrays[i][j]+",");;
                }
                System.out.println();
            }
        }
    }
    @NoArgsConstructor
    @AllArgsConstructor
    public class StringRoll{
        private String str1;
        private String str2;
        /**
         * 1.inited: wate
         * 2.rolled: erbottlewat
         *      waterbottle
         *       erbottlewaterbottlewat
         *
         *      rbottlewat
         */
        private boolean isSubstring(String newStr ){
           return newStr.contains(str1);
        }
        public boolean isRollString(){
            String newStr = str2+str2;
            return isSubstring(newStr);
        }

    }

}
